package com.woniuxy.yygh.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.common.rabbit.constant.MqConst;
import com.woniuxy.common.rabbit.service.RabbitService;
import com.woniuxy.yygh.common.helper.HttpRequestHelper;
import com.woniuxy.yygh.enums.OrderStatusEnum;
import com.woniuxy.yygh.user.client.HospitalFeignClient;
import com.woniuxy.yygh.user.client.PatientFeignClient;
import com.woniuxy.yygh.model.order.OrderInfo;
import com.woniuxy.yygh.model.user.Patient;
import com.woniuxy.yygh.order.mapper.OrderMapper;
import com.woniuxy.yygh.order.service.OrderService;
import com.woniuxy.yygh.vo.hosp.ScheduleOrderVo;
import com.woniuxy.yygh.vo.msm.MsmVo;
import com.woniuxy.yygh.vo.order.OrderMqVo;
import com.woniuxy.yygh.vo.order.OrderQueryVo;
import com.woniuxy.yygh.vo.order.SignInfoVo;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Executors;

/**
 * <P> @Author: ideaAdmin
 * <P> TODO: Class
 * <P> TODO: 订单实现类
 * <P> Date: 2022/3/6:10:01
 * <P> Description:
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, OrderInfo> implements OrderService {
    /**
     * TODO 注入远程病人信息接口
     */
    @Autowired
    private PatientFeignClient patientFeignClient;

    /**
     * TODO 注入远程医院信息接口
     */
    @Autowired
    private HospitalFeignClient hospitalFeignClient;

    @Autowired
    private RabbitService rabbitService;


    /**
     * TODO:根据排班id和就诊人id 生成挂号的订单
     **/
    @Override
    public Long saveOrder(String scheduleId, Long patientId) {
        //scheduleId = 1+"";
        //获取就诊人信息
        Patient patient = patientFeignClient.getPatientOrder(patientId);

        //获取排班相关信息
        ScheduleOrderVo scheduleOrderVo =
                hospitalFeignClient.getScheduleOrderVo(scheduleId);

        //通过医院编号获取医院的密钥
        SignInfoVo signInfoVo =
                hospitalFeignClient.getSignInfoVo(scheduleOrderVo.getHoscode());

        //添加到订单表
        OrderInfo orderInfo = new OrderInfo();

        //把scheduleOrderVo 复制到orderInfo中
        BeanUtils.copyProperties(scheduleOrderVo, orderInfo);

        //订单交易号
        String outTradeNo = System.currentTimeMillis() + "" + new Random().nextInt(100);
        orderInfo.setOutTradeNo(outTradeNo);
        //排班id
        orderInfo.setScheduleId(scheduleId);
        //用户id
        orderInfo.setUserId(patient.getUserId());
        //就诊人id
        orderInfo.setPatientId(patientId);
        //就诊人名称
        orderInfo.setPatientName(patient.getName());
        //就诊人电话
        orderInfo.setPatientPhone(patient.getPhone());
        //订单状态 ：预约成功，待支付
        orderInfo.setOrderStatus(OrderStatusEnum.UNPAID.getStatus());

        //插入数据
        baseMapper.insert(orderInfo);

        //调用医院接口 实现预约挂号操作
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("hoscode", orderInfo.getHoscode());
        paramMap.put("depcode", orderInfo.getDepcode());
        paramMap.put("hosScheduleId", orderInfo.getScheduleId());
        paramMap.put("reserveDate", new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd"));
        paramMap.put("reserveTime", orderInfo.getReserveTime());
        paramMap.put("amount", orderInfo.getAmount());
        paramMap.put("name", patient.getName());
        paramMap.put("certificatesType", patient.getCertificatesType());
        paramMap.put("certificatesNo", patient.getCertificatesNo());
        paramMap.put("sex", patient.getSex());
        paramMap.put("birthdate", patient.getBirthdate());
        paramMap.put("phone", patient.getPhone());
        paramMap.put("isMarry", patient.getIsMarry());
        paramMap.put("provinceCode", patient.getProvinceCode());
        paramMap.put("cityCode", patient.getCityCode());
        paramMap.put("districtCode", patient.getDistrictCode());
        paramMap.put("address", patient.getAddress());
        //联系人
        paramMap.put("contactsName", patient.getContactsName());
        paramMap.put("contactsCertificatesType", patient.getContactsCertificatesType());
        paramMap.put("contactsCertificatesNo", patient.getContactsCertificatesNo());
        paramMap.put("contactsPhone", patient.getContactsPhone());
        paramMap.put("timestamp", HttpRequestHelper.getTimestamp());
        String sign = HttpRequestHelper.getSign(paramMap, signInfoVo.getSignKey());
        paramMap.put("sign", sign);


//
        //发送mq信息更新号源和短信通知

        //发送mq进行号源更新
        OrderMqVo orderMqVo = new OrderMqVo();
        orderMqVo.setScheduleId(scheduleId);
//            //可预约数
        orderMqVo.setReservedNumber(scheduleOrderVo.getReservedNumber() - 1);
        //剩余预约数
        orderMqVo.setAvailableNumber(scheduleOrderVo.getAvailableNumber() - 1);
        orderMqVo.setScheduleId(scheduleId);
//
        //短信提示
        MsmVo msmVo = new MsmVo();
        msmVo.setPhone(orderInfo.getPatientPhone());
        // msmVo.setPhone(orderInfo.getPatientPhone());
        msmVo.setTemplateCode("SMS_226526200");

        String reserveDate =
                new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd")
                        + (orderInfo.getReserveTime() == 0 ? "上午" : "下午");
        Map<String, Object> param = new HashMap<String, Object>();

        param.put("code", "orderIsSuccess");
        msmVo.setParam(param);
//
        orderMqVo.setMsmVo(msmVo);

        //发送
        rabbitService.sendMessage(
                MqConst.EXCHANGE_DIRECT_ORDER,
                MqConst.ROUTING_ORDER,
                orderMqVo);
//


        //返回订单id
        return orderInfo.getId();
    }

    /**
     * TODO:根据订单id查询订单详情
     **/
    @Override
    public OrderInfo getOrder(String orderId) {
        OrderInfo orderInfo = baseMapper.selectById(orderId);
        return this.packOrderInfo(orderInfo);
    }

    /**
     * TODO:获取用户的所有列表 分页
     **/
    @Override
    public IPage<OrderInfo> selectPage(Page<OrderInfo> pageParam, OrderQueryVo orderQueryVo) {
        //多条件值
        //用户id 就诊人id 订单状态
        //医院名称
        String hosname = orderQueryVo.getKeyword();
        //就诊人名字
        Long patientId = orderQueryVo.getPatientId();
        //订单状态
        String orderStatus = orderQueryVo.getOrderStatus();
        //安排日期
        String reserveDate = orderQueryVo.getReserveDate();
        //开始时间和结束时间
        String createTimeBegin = orderQueryVo.getCreateTimeBegin();
        String createTimeEnd = orderQueryVo.getCreateTimeEnd();


        //对条件值进行判断是否为空
        //如果不为空 则设置值
        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(hosname)) {
            wrapper.eq("hosname", hosname);
        }

        if (!StringUtils.isEmpty(patientId)) {
            wrapper.eq("patient_id", patientId);
        }

        if (!StringUtils.isEmpty(orderStatus)) {
            wrapper.eq("order_status", orderStatus);
        }

        if (!StringUtils.isEmpty(reserveDate)) {
            //查询大于这个安排的时间
            wrapper.ge("reserve_date", reserveDate);
        }

        if (!StringUtils.isEmpty(createTimeEnd)) {
            //小于这个创建的时间
            wrapper.le("create_time", createTimeEnd);
        }
        wrapper.ge("quit_time", new Date());
        wrapper.orderByDesc("create_time");
        Page<OrderInfo> pages = baseMapper.selectPage(pageParam, wrapper);

        //编号获得对应值
        pages.getRecords().stream().forEach(item -> {
            this.packOrderInfo(item);
        });
        return pages;
    }

    /**
     * TODO:根据订单取消预约
     **/
    @Override
    public boolean cancelOrder(String orderId) {
        //获取订单信息
        OrderInfo orderInfo = baseMapper.selectById(orderId);

        //查询用户的信息
        //获取就诊人信息
        Patient patient = patientFeignClient.getPatientOrder(orderInfo.getUserId());


        //通过退号时间 判断是否可以取消
        DateTime dateTime = new DateTime(orderInfo.getQuitTime());


        ScheduleOrderVo scheduleOrderVo =
                hospitalFeignClient.getScheduleOrderVo(orderInfo.getScheduleId());


        //发送mq进行号源更新
        OrderMqVo orderMqVo = new OrderMqVo();
        orderMqVo.setScheduleId(orderInfo.getScheduleId());
        //可预约数
        orderMqVo.setReservedNumber(scheduleOrderVo.getReservedNumber() + 1);
        //剩余预约数
        orderMqVo.setAvailableNumber(scheduleOrderVo.getAvailableNumber() + 1);


        //短信提示
        MsmVo msmVo = new MsmVo();
        msmVo.setPhone(patient.getPhone());

        msmVo.setTemplateCode("SMS_226526200");


        Map<String, Object> param = new HashMap<String, Object>();

        param.put("code", "cancelOrderIsSuccess");
        msmVo.setParam(param);

        orderMqVo.setMsmVo(msmVo);


        rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_ORDER, MqConst.ROUTING_ORDER, orderMqVo);

        orderInfo.setOrderStatus(OrderStatusEnum.CANCLE.getStatus());

        //更新订单id更新整个订单
        int i = baseMapper.updateById(orderInfo);

        return i > 0;
    }

    /**
     * TODO:管理员根据订单取消预约
     **/

    @Override
    public boolean adminCancelOrder(String orderId) {
        //获取订单信息
        OrderInfo orderInfo = baseMapper.selectById(orderId);


        //查询用户的信息
        //获取就诊人信息
        Patient patient = patientFeignClient.getPatientOrder(orderInfo.getUserId());


        ScheduleOrderVo scheduleOrderVo =
                hospitalFeignClient.getScheduleOrderVo(orderInfo.getScheduleId());


        //发送mq进行号源更新
        OrderMqVo orderMqVo = new OrderMqVo();
        orderMqVo.setScheduleId(orderInfo.getScheduleId());
        //可预约数
        orderMqVo.setReservedNumber(scheduleOrderVo.getReservedNumber() + 1);
        //剩余预约数
        orderMqVo.setAvailableNumber(scheduleOrderVo.getAvailableNumber() + 1);

        //短信提示
        MsmVo msmVo = new MsmVo();
        msmVo.setPhone(patient.getPhone());

        msmVo.setTemplateCode("SMS_226526200");


        Map<String, Object> param = new HashMap();

        param.put("code", "cancelOrderIsSuccess");
        msmVo.setParam(param);

        orderMqVo.setMsmVo(msmVo);

        //发送
        rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_ORDER, MqConst.ROUTING_ORDER, orderMqVo);
        //调用医院接口 取消预约
        orderInfo.setOrderStatus(OrderStatusEnum.CANCLE.getStatus());

        int i = baseMapper.updateById(orderInfo);

        return i > 0;
    }

    /**
     * TODO:根据状态码 返回对应是否支付信息
     **/
    private OrderInfo packOrderInfo(OrderInfo orderInfo) {
        orderInfo.getParam().put("orderStatusString",
                OrderStatusEnum.getStatusNameByStatus(orderInfo.getOrderStatus()));
        return orderInfo;
    }


}
